<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Facades\DB;

class SubSettlement extends Model
{
    protected $table = 'sub_settlements';

    // 不使用自增主键，使用雪花ID
    public $incrementing = false;
    protected $keyType = 'string';

    // 状态常量（中文值，减少枚举与字面量转换）
    public const STATUS_PENDING_VERIFY     = '待验证';
    public const STATUS_VERIFYING          = '验证中';
    public const STATUS_PENDING_TAX        = '待算税';
    public const STATUS_PENDING_SUBMIT     = '待提交';
    public const STATUS_PENDING_DISTRIBUTE = '待发放';
    public const STATUS_DISTRIBUTING       = '发放中';
    public const STATUS_COMPLETED          = '已完成';
    public const STATUS_CANCELLED          = '已取消';
    public const STATUS_DISTRIBUTE_FAILED  = '发放失败';
    public const STATUS_VERIFY_FAILED      = '验证失败';
    public const STATUS_REFUNDED           = '已退票';

    public const STATUS_LABELS = [
        self::STATUS_PENDING_VERIFY     => '待验证',
        self::STATUS_VERIFYING          => '验证中',
        self::STATUS_PENDING_TAX        => '待算税',
        self::STATUS_PENDING_SUBMIT     => '待提交',
        self::STATUS_PENDING_DISTRIBUTE => '待发放',
        self::STATUS_DISTRIBUTING       => '发放中',
        self::STATUS_COMPLETED          => '已完成',
        self::STATUS_CANCELLED          => '已取消',
        self::STATUS_DISTRIBUTE_FAILED  => '发放失败',
        self::STATUS_VERIFY_FAILED      => '验证失败',
        self::STATUS_REFUNDED           => '已退票',
    ];

    protected $fillable = [
        'id',
        'tenant_id',
        'settlement_id', 
        'freelancer_id',
        'freelancer_name',
        'freelancer_phone',
        'freelancer_id_card',
        'freelancer_bank_account',
        'freelancer_bank_name',
        'pre_settlement_amount',
        'commission',
        'service_fee',
        'service_fee_rate',
        'tax',
        'required_balance',
        'status',
        'status_description',
        'bank_batch_id',
        'payment_remarks',
        'electronic_receipt',
        'verified_at',
        'submitted_at',
        'distribute_started_at',
        'distributed_at',
        'cancelled_at',
        'created_by',
        'verified_by',
        'submitted_by',
        'distributed_by',
        'cancelled_by'
    ];

    protected $casts = [
        'id' => 'string',
        'settlement_id' => 'string',
        'freelancer_id' => 'string',
        'pre_settlement_amount' => 'decimal:2',
        'commission' => 'decimal:2',
        'service_fee' => 'decimal:2',
        'service_fee_rate' => 'decimal:4',
        'tax' => 'decimal:2',
        'required_balance' => 'decimal:2',
        'electronic_receipt' => 'json',
        'verified_at' => 'datetime',
        'submitted_at' => 'datetime',
        'distribute_started_at' => 'datetime',
        'distributed_at' => 'datetime',
        'cancelled_at' => 'datetime',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    public function getIdAttribute($value): string
    {
        return (string) $value;
    }

    protected $appends = [
        'status_display',
        'sub_settlement_number'
    ];

    /**
     * 生成雪花ID
     */
    public static function generateSnowflakeId(): string
    {
        // 时间戳（毫秒）
        $timestamp = (int)(microtime(true) * 1000);
        
        // 机器ID（这里使用简单的随机数，生产环境应该使用配置的机器ID）
        $machineId = mt_rand(0, 1023); // 10位
        
        // 序列号（这里使用简单的随机数，生产环境应该使用递增序列）
        $sequence = mt_rand(0, 4095); // 12位
        
        // 组装雪花ID: 时间戳(42位) + 机器ID(10位) + 序列号(12位)
        $snowflakeId = ($timestamp << 22) | ($machineId << 12) | $sequence;
        
        return (string)$snowflakeId;
    }

    /**
     * 创建时自动生成雪花ID
     */
    protected static function boot()
    {
        parent::boot();
        
        static::creating(function ($model) {
            if (empty($model->id)) {
                $model->id = static::generateSnowflakeId();
            }
        });
    }

    /**
     * 获取状态显示文本
     */
    public function getStatusDisplayAttribute(): string
    {
        return self::STATUS_LABELS[$this->status] ?? $this->status;
    }

    /**
     * 获取子结算单编号
     */
    public function getSubSettlementNumberAttribute(): string
    {
        return 'SUB' . substr($this->id, -8);
    }

    /**
     * 关联租户
     */
    public function tenant(): BelongsTo
    {
        return $this->belongsTo(Tenant::class);
    }

    /**
     * 关联结算单
     */
    public function settlement(): BelongsTo
    {
        return $this->belongsTo(Settlement::class);
    }

    /**
     * 关联自由职业者
     */
    public function freelancer(): BelongsTo
    {
        return $this->belongsTo(Freelancer::class);
    }

    /**
     * 租户作用域
     */
    public function scopeTenant($query, $tenantId)
    {
        return $query->where('tenant_id', $tenantId);
    }

    /**
     * 状态作用域
     */
    public function scopeStatus($query, $status)
    {
        return $query->where('status', $status);
    }

    /**
     * 按结算单筛选
     */
    public function scopeBySettlement($query, $settlementId)
    {
        return $query->where('settlement_id', $settlementId);
    }

    /**
     * 按自由职业者筛选
     */
    public function scopeByFreelancer($query, $freelancerId)
    {
        return $query->where('freelancer_id', $freelancerId);
    }

    /**
     * 搜索自由职业者
     */
    public function scopeSearchFreelancer($query, $keyword)
    {
        return $query->where(function($q) use ($keyword) {
            $q->where('freelancer_name', 'like', "%{$keyword}%")
              ->orWhere('freelancer_phone', 'like', "%{$keyword}%")
              ->orWhere('freelancer_id_card', 'like', "%{$keyword}%");
        });
    }

    /**
     * 按创建时间范围筛选
     */
    public function scopeDateRange($query, $startDate, $endDate)
    {
        return $query->whereBetween('created_at', [$startDate, $endDate]);
    }

    /**
     * 验证子结算单
     */
    public function verify($verifiedBy, $remarks = null): bool
    {
        if ($this->status !== self::STATUS_VERIFYING) {
            return false;
        }

        return $this->update([
            'status' => self::STATUS_PENDING_SUBMIT,
            'verified_at' => now(),
            'verified_by' => $verifiedBy,
            'status_description' => $remarks
        ]);
    }

    /**
     * 验证失败
     */
    public function verifyFailed($verifiedBy, $remarks): bool
    {
        if ($this->status !== self::STATUS_VERIFYING) {
            return false;
        }

        return $this->update([
            'status' => self::STATUS_VERIFY_FAILED,
            'verified_at' => now(),
            'verified_by' => $verifiedBy,
            'status_description' => $remarks
        ]);
    }

    /**
     * 提交子结算单
     */
    public function submit($submittedBy): bool
    {
        if ($this->status !== self::STATUS_PENDING_SUBMIT) {
            return false;
        }

        return $this->update([
            'status' => self::STATUS_PENDING_DISTRIBUTE,
            'submitted_at' => now(),
            'submitted_by' => $submittedBy
        ]);
    }

    /**
     * 开始发放
     */
    public function startDistribute($distributedBy): bool
    {
        if ($this->status !== self::STATUS_PENDING_DISTRIBUTE) {
            return false;
        }

        return $this->update([
            'status' => self::STATUS_DISTRIBUTING,
            'distribute_started_at' => now(),
            'distributed_by' => $distributedBy
        ]);
    }

    /**
     * 发放完成
     */
    public function completeDistribute($distributedBy, $electronicReceipt = null): bool
    {
        if ($this->status !== self::STATUS_DISTRIBUTING) {
            return false;
        }

        $updateData = [
            'status' => self::STATUS_COMPLETED,
            'distributed_at' => now(),
            'distributed_by' => $distributedBy
        ];

        if ($electronicReceipt) {
            $updateData['electronic_receipt'] = $electronicReceipt;
        }

        return $this->update($updateData);
    }

    /**
     * 发放失败
     */
    public function distributeFailed($distributedBy, $remarks): bool
    {
        if ($this->status !== self::STATUS_DISTRIBUTING) {
            return false;
        }

        return $this->update([
            'status' => self::STATUS_DISTRIBUTE_FAILED,
            'distributed_by' => $distributedBy,
            'status_description' => $remarks
        ]);
    }

    /**
     * 取消子结算单
     */
    public function cancel($cancelledBy, $remarks = null): bool
    {
        if (in_array($this->status, [self::STATUS_COMPLETED, self::STATUS_CANCELLED, self::STATUS_REFUNDED])) {
            return false;
        }

        return $this->update([
            'status' => self::STATUS_CANCELLED,
            'cancelled_at' => now(),
            'cancelled_by' => $cancelledBy,
            'status_description' => $remarks
        ]);
    }

    /**
     * 退票
     */
    public function refund($operatedBy, $remarks): bool
    {
        if ($this->status !== self::STATUS_COMPLETED) {
            return false;
        }

        return $this->update([
            'status' => self::STATUS_REFUNDED,
            'status_description' => $remarks,
            'updated_at' => now()
        ]);
    }

    /**
     * 同步自由职业者信息
     */
    public function syncFreelancerInfo()
    {
        if (!$this->freelancer) {
            return false;
        }

        return $this->update([
            'freelancer_name' => $this->freelancer->name,
            'freelancer_phone' => $this->freelancer->phone,
            'freelancer_id_card' => $this->freelancer->id_card,
            'freelancer_bank_account' => $this->freelancer->bank_account,
            'freelancer_bank_name' => $this->freelancer->bank_name
        ]);
    }

    /**
     * 计算服务费
     */
    public function calculateServiceFee()
    {
        $this->service_fee = $this->pre_settlement_amount * $this->service_fee_rate;
        $this->commission = $this->pre_settlement_amount - ($this->tax ?? 0.0);
        $this->required_balance = max(0.0, $this->pre_settlement_amount + $this->service_fee);
    }

    /**
     * 获取所有状态选项
     */
    public static function getStatusOptions(): array
    {
        return [
            self::STATUS_PENDING_VERIFY     => '待验证',
            self::STATUS_VERIFYING          => '验证中',
            self::STATUS_PENDING_TAX        => '待算税',
            self::STATUS_PENDING_SUBMIT     => '待提交',
            self::STATUS_PENDING_DISTRIBUTE => '待发放',
            self::STATUS_DISTRIBUTING       => '发放中',
            self::STATUS_COMPLETED          => '已完成',
            self::STATUS_CANCELLED          => '已取消',
            self::STATUS_DISTRIBUTE_FAILED  => '发放失败',
            self::STATUS_VERIFY_FAILED      => '验证失败',
            self::STATUS_REFUNDED           => '已退票'
        ];
    }
}
